package com.zs.letcode.illustration_of_algorithm;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 剑指 Offer 33. 二叉搜索树的后序遍历序列
 * 输入一个整数数组，判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true，否则返回false。假设输入的数组的任意两个数字都互不相同。
 * <p>
 * <p>
 * 参考以下这颗二叉搜索树：
 * <p>
 * 5
 * / \
 * 2   6
 * / \
 * 1   3
 * 示例 1：
 * <p>
 * 输入: [1,6,3,2,5]
 * 输出: false
 * 示例 2：
 * <p>
 * 输入: [1,3,2,6,5]
 * 输出: true
 *
 * <p>
 * 提示：
 * <p>
 * 数组长度 <= 1000
 * 相关标签
 * 栈
 * 树
 * 二叉搜索树
 * 递归
 * 二叉树
 * 单调栈
 * <p>
 * 作者：Krahets
 * 链接：https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5vwxx5/
 * 来源：力扣（LeetCode）
 * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
 *
 * @author madison
 * @description
 * @date 2021/8/22 10:16
 */
public class Chapter43 {
    public static void main(String[] args) {

    }

    private class Solution {
        /**
         * 方法一：递归分治
         */
        public boolean verifyPostorder(int[] postorder) {
            return recur(postorder, 0, postorder.length - 1);
        }

        private boolean recur(int[] postorder, int i, int j) {
            if (i >= j) {
                return true;
            }
            int p = i;
            while (postorder[p] < postorder[j]) {
                p++;
            }
            int m = p;
            while (postorder[p] > postorder[j]) {
                p++;
            }
            return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
        }

        /**
         * 方法二：辅助单调栈
         */
        public boolean verifyPostorder1(int[] postorder) {
            Deque<Integer> stack = new LinkedList<>();
            int root = Integer.MAX_VALUE;
            for (int i = postorder.length - 1; i >= 0; i--) {
                if (postorder[i] > root) {
                    return false;
                }
                while (!stack.isEmpty() && stack.peek() > postorder[i]) {
                    root = stack.pop();
                }
                stack.push(postorder[i]);
            }
            return true;
        }
    }
}
